/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * @file           : main.c
 * @brief          : Main program body
 ******************************************************************************
 * @attention
 *
 * Copyright (c) 2025 STMicroelectronics.
 * All rights reserved.
 *
 * This software is licensed under terms that can be found in the LICENSE file
 * in the root directory of this software component.
 * If no LICENSE file comes with this software, it is provided AS-IS.
 *
 ******************************************************************************
 */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "DBs/DB0.h"
#include "DBs/DB1.h"
#include "bitLogic.h"
#include "command_test.h"
#include "delay.h"
#include "global.h"
#include "gpio.h"
#include "rising_dege.h"
#include "soft_timer_on.h"
#include "stm32f4xx_hal_def.h"
#include "stm32f4xx_hal_gpio.h"
#include "stm32f4xx_hal_tim.h"
#include "timer_operation.h"
#include "usart.h"
#include "util.h"
#include <string.h>

TIM_HandleTypeDef g_tim6_handle; /* 定时器6句柄 */
u16 gWms;
u16 GWs[10];

BitStruce Input[2];  /* 输入状态结构体数组 */
BitStruce Output[2]; /* 输出状态结构体数组 */

RisingEdgeMonitor rising_edge_buffer[10]; /* 上升沿检测器缓冲区 */
RisingEdgeDetector rising_edge_detector;  /* 上升沿检测器实例 */
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/

u8 SystemClock_Config(u32 plln, u32 pllm, u32 pllp, u32 pllq);
/**
 * @brief 定时器初始化
 *
 */
void gtim_tim6_int_init(void);
/**
 * @brief 时钟回调
 *
 */
void SysTick_USR_cb(void);
void timer_int_1ms(void);
/**
 * @brief modbus解析
 *
 */
void process_modbus_frame(void);

/**
 * @brief 启动配置
 *
 */
void startup(void);

/**
 * @brief 刷新输入输出状态
 *
 */
void update_io(void);
void updata_io_set(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/*region mbRTU*/

// uint8_t registers_DB1_data[REG_SIZE] = {0};
// DB1 *DB1_data = (DB1 *)registers_DB1_data;
// uint8_t *registers = registers_DB1_data;

Byte plc_DB[REG_NUMBER][REG_SIZE] = {0}; // 寄存器数组
volatile Time system_run_time = 0;
void process_modbus_frame(void) {
  if (ser3_RdFlag != 0x01)
    return;

  // 验证从机地址
  if (ser3_RB[0] != SLAVE_ADDR) {
    ser3_RdFlag = 0;
    ser3_RdNum = 0;
    return;
  }

  // 验证 CRC
  uint16_t crc_received =
      (ser3_RB[ser3_RdNum - 1] << 8) | ser3_RB[ser3_RdNum - 2];
  uint16_t crc_calculated = modbus_crc16((uint8_t *)ser3_RB, ser3_RdNum - 2);
  if (crc_received != crc_calculated) {
    ser3_RdFlag = 0;
    ser3_RdNum = 0;
    return;
  }

  uint8_t func = ser3_RB[1];
  uint16_t addr = ((ser3_RB[2] << 8) | ser3_RB[3]) & 0x3FF;
  uint16_t count = (ser3_RB[4] << 8) | ser3_RB[5];
  // 假设 DB 编号固定为 0（如果需要动态选择
  // DB，可从协议帧中解析）可通过偏移量计算，后期在后续版本中实现
  /*比如1KB，则用偏移量和0x0400做&运算，得到所在数组*/

  uint8_t db_index = ser3_RB[2] >> 2; // 可根据实际需求修改
  // uint8_t tx_buffer[20];
  ser3_TB[0] = SLAVE_ADDR;
  ser3_TB[1] = func;

  if (func == 0x03) { // 读寄存器
    uint8_t byte_count = count * 2;
    ser3_TB[2] = byte_count;
    for (uint16_t i = 0; i < count; i++) {
      // 调整大小端
      ser3_TB[3 + i * 2] = plc_DB[db_index][addr * 2 + i * 2 + 1]; // 高字节
      ser3_TB[4 + i * 2] = plc_DB[db_index][addr * 2 + i * 2];     // 低字节
    }
    uint16_t crc = modbus_crc16((uint8_t *)ser3_TB, 3 + byte_count);
    ser3_TB[3 + byte_count] = crc & 0xFF;        // 低字节
    ser3_TB[4 + byte_count] = (crc >> 8) & 0xFF; // 高字节
    ser3_Write(ser3_TB, 5 + byte_count);
  } else if (func == 0x01) {    // 读 Coil
    uint8_t byte_count = count; // 每个 Coil 占用 1 字节
    ser3_TB[2] = byte_count;
    for (uint8_t i = 0; i < byte_count; i++) {
      ser3_TB[3 + i] = plc_DB[db_index][addr + i];
    }
    uint16_t crc = modbus_crc16((uint8_t *)ser3_TB, 3 + byte_count);
    ser3_TB[3 + byte_count] = crc & 0xFF;
    ser3_TB[4 + byte_count] = (crc >> 8) & 0xFF;
    ser3_Write(ser3_TB, 5 + byte_count);
  } else if (func == 0x06) { // 写单个寄存器
    uint16_t value = (ser3_RB[4] << 8) | ser3_RB[5];

    // 检查地址范围
    if (addr * 2 + 1 < REG_SIZE) {
      // 写入 registers（小端序）
      plc_DB[db_index][addr * 2] = value >> 8;       // 高字节
      plc_DB[db_index][addr * 2 + 1] = value & 0xFF; // 低字节

      // 回显请求帧
      memcpy(ser3_TB, ser3_RB, 8);
      ser3_Write(ser3_TB, 8);
    } else {
      // 地址越界，返回错误（功能码 + 0x80，异常码 02）
      ser3_TB[1] = 0x86;
      ser3_TB[2] = 0x02; // 非法数据地址
      uint16_t crc = modbus_crc16((uint8_t *)ser3_TB, 3);
      ser3_TB[3] = crc & 0xFF;
      ser3_TB[4] = (crc >> 8) & 0xFF;
      ser3_Write(ser3_TB, 8);
    }
  }

  ser3_RdFlag = 0;
  ser3_RdNum = 0;
}
/*endregion*/
/* USER CODE END 0 */

// SampleTable_s.StartButton = 0; // Access its member correctly
// SampleTable_s.EndButton = 0;
/**
 * @brief  The application entry point.
 * @retval int
 */
int main(void) {

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick.
   */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  /* 设置时钟,168Mhz */
  if (SystemClock_Config(336, 8, 2, 7) != HAL_OK) {
    return HAL_ERROR;
  };

  /* USER CODE BEGIN SysInit */
  delay_init(168);
  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  gtim_tim6_int_init();
  MX_USART3_UART_Init();
  startup(); // 启动配置
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  char str[4] = {0x10, 0x11, 0x12, 0x13};
  int a = 0x14;
  // 新的延时接通
  IEC_Timer timer_instance1 = {false, 3000, 0,    false,
                               false, 0,    false}; // 初始化定时器，PT = 3000ms
  IEC_Timer timer_instance2 = {
      false, 30000, 0, false, false, 0, false}; // 初始化定时器，PT = 3000ms
  Bool res1 = false;
  Bool bit1 = false;
  Bool bit2 = false; // 上升沿
  ser3_send_log("start test");
	
  test_compare();
  test_add();
  test_mul();
  test_div_sub();
  test_mod();
  test_inc_dec();
  testPContact();
  testNContact();
  test_PCoil();
  test_NCoil();
  ser3_send_log("end test");
	delay_ms(200);
  ser3_send_log("start main loop");
  while (1) {
    // 更新
    update_io(); // 更新输入输出状态
    // detect_rising_edges(&rising_edge_detector); // 检测上升沿
    // if (Input[0].bit0 == 0x01) {
    //   HAL_GPIO_WritePin(Q01_GPIO_Port, Q01_Pin, GPIO_PIN_SET);
    // } else {
    //  HAL_GPIO_WritePin(Q01_GPIO_Port, Q01_Pin, GPIO_PIN_RESET);
    //}

    // if (is_rising_edge_triggered(&rising_edge_detector, &Input[0].bit0)) {
    //  处理上升沿触发事件
    //  HAL_GPIO_TogglePin(Q05_GPIO_Port, Q05_Pin); // 切换LED状态
    // HAL_GPIO_WritePin(Q00_GPIO_Port, Q00_Pin, GPIO_PIN_SET);
    // delay_ms(1000);
    //} else {
    //  HAL_GPIO_WritePin(Q00_GPIO_Port, Q00_Pin, GPIO_PIN_RESET);
    //}
    /* USER CODE END WHILE */

    // ser3_Write(str, 4);
    delay_ms(100);
    ++a;
    str[3] = a;
    /* USER CODE BEGIN 3 */
    /*灯闪*/
    HAL_GPIO_WritePin(Q05_GPIO_Port, Q05_Pin, GPIO_PIN_SET);

    /*定时器 第三个输入点*/
    // if (TON1.output == 1) {
    //   HAL_GPIO_WritePin(Q02_GPIO_Port, Q02_Pin, GPIO_PIN_SET); // 亮
    // }
    /*定时器 第四个输入点*/
    // if (TON2.output == 1) {
    //   HAL_GPIO_WritePin(Q02_GPIO_Port, Q02_Pin, GPIO_PIN_RESET); // 灭
    // }

    // 网络1
    {
      // 一路
      res1 = true;
      res1 = Contact(res1, Input[0].bit6);
      res1 = TON(res1, timer_instance1.PT, system_run_time, &timer_instance1);
      HAL_GPIO_WritePin(Q06_GPIO_Port, Q06_Pin, (GPIO_PinState)res1);
      res1 = Coil(res1, &Output[0].bit6);
      PCoil(timer_instance1.IN, &Output[0].bit0, &bit1);
      if (Output[0].bit0 == true) {
        ser3_send_log("ton start");
        Output[0].bit0 = false;
      }
      res1 = PCoil(timer_instance1.Q, &Output[0].bit1, &bit2);
      if (Output[0].bit1 == true) {
        ser3_send_log("ton end");
        Output[0].bit1 = false;
      }

      // 一路
      res1 = true;
      res1 = Contact(res1, Input[0].bit4);

      res1 = TON(res1, timer_instance1.PT, system_run_time, &timer_instance2);
      HAL_GPIO_WritePin(Q04_GPIO_Port, Q04_Pin, (GPIO_PinState)res1);
      res1 = Coil(res1, &Output[0].bit4);

      // 二路
      res1 = true;
      res1 = Contact(res1, Input[0].bit7);
      res1 = Not(res1);
      res1 = Coil(res1, &Output[0].bit7);

      // 三路
      res1 = true;
      res1 = Contact(res1, Input[1].bit0);
      res1 = Contact(res1, Input[1].bit1);
      res1 = ResetIECTimerCoil(res1, &timer_instance1);
    }
    loop_DB0();             // 循环DB0数据块测试用
    loop_DB1();             // 循环DB1数据块测试用
    updata_io_set();        // 更新输出
    process_modbus_frame(); // 解析modbusrtu
  }
  /* USER CODE END 3 */
}

/**
 * @brief 时钟设置函数 （系统核心）
 *
 * @param       plln: 主PLL倍频系数(PLL倍频), 取值范围: 64~432.
 * @param       pllm: 主PLL和音频PLL预分频系数(进PLL之前的分频), 取值范围: 2~63.
 * @param       pllp: 主PLL的p分频系数(PLL之后的分频), 分频后作为系统时钟,
 * 取值范围: 2, 4, 6, 8.(仅限这4个值)
 * @param       pllq: 主PLL的q分频系数(PLL之后的分频), 取值范围: 2~15.
 * @note
 *
 *              Fvco: VCO频率
 *              Fsys: 系统时钟频率, 也是主PLL的p分频输出时钟频率
 *              Fq:   主PLL的q分频输出时钟频率
 *              Fs:   主PLL输入时钟频率, 可以是HSI, HSE等.
 *              Fvco = Fs * (plln / pllm);
 *              Fsys = Fvco / pllp = Fs * (plln / (pllm * pllp));
 *              Fq   = Fvco / pllq = Fs * (plln / (pllm * pllq));
 *
 *              外部晶振为 8M的时候, 推荐值: plln = 336, pllm = 8, pllp = 2,
 * pllq = 7. 得到:Fvco = 8 * (336 / 8) = 336Mhz Fsys = pll_p_ck = 336 / 2 =
 * 168Mhz Fq   = pll_q_ck = 336 / 7 = 48Mhz
 *
 *              F407默认需要配置的频率如下:
 *              CPU频率(HCLK) = pll_p_ck = 168Mhz
 *              AHB1/2/3(rcc_hclk1/2/3) = 168Mhz
 *              APB1(rcc_pclk1) = pll_p_ck / 4 = 42Mhz
 *              APB1(rcc_pclk2) = pll_p_ck / 2 = 84Mhz
 * @return u8 0 成功, 非0失败.
 */
u8 SystemClock_Config(u32 plln, u32 pllm, u32 pllp, u32 pllq) {
  HAL_StatusTypeDef ret = HAL_OK;
  RCC_OscInitTypeDef rcc_osc_init = {0};
  RCC_ClkInitTypeDef rcc_clk_init = {0};

  __HAL_RCC_PWR_CLK_ENABLE(); /* 使能PWR时钟 */

  __HAL_PWR_VOLTAGESCALING_CONFIG(
      PWR_REGULATOR_VOLTAGE_SCALE1); /* 设置调压器输出电压级别，以便在器件未以最大频率工作
                                      */

  /* 使能HSE，并选择HSE作为PLL时钟源，配置PLL1，开启USB时钟 */
  rcc_osc_init.OscillatorType = RCC_OSCILLATORTYPE_HSE; /* 时钟源为HSE */
  rcc_osc_init.HSEState = RCC_HSE_ON;                   /* 打开HSE */
  rcc_osc_init.PLL.PLLState = RCC_PLL_ON;               /* 打开PLL */
  rcc_osc_init.PLL.PLLSource = RCC_PLLSOURCE_HSE;       /* PLL时钟源选择HSE */
  rcc_osc_init.PLL.PLLN = plln;
  rcc_osc_init.PLL.PLLM = pllm;
  rcc_osc_init.PLL.PLLP = pllp;
  rcc_osc_init.PLL.PLLQ = pllq;
  ret = HAL_RCC_OscConfig(&rcc_osc_init); /* 初始化RCC */
  if (ret != HAL_OK) {
    return 1; /* 时钟初始化失败，可以在这里加入自己的处理 */
  }

  /* 选中PLL作为系统时钟源并且配置HCLK,PCLK1和PCLK2 */
  rcc_clk_init.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK |
                            RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);

  rcc_clk_init.SYSCLKSource =
      RCC_SYSCLKSOURCE_PLLCLK;                  /* 设置系统时钟时钟源为PLL */
  rcc_clk_init.AHBCLKDivider = RCC_SYSCLK_DIV1; /* AHB分频系数为1 */
  rcc_clk_init.APB1CLKDivider = RCC_HCLK_DIV4;  /* APB1分频系数为4 */
  rcc_clk_init.APB2CLKDivider = RCC_HCLK_DIV2;  /* APB2分频系数为2 */
  ret = HAL_RCC_ClockConfig(
      &rcc_clk_init,
      FLASH_LATENCY_5); /* 同时设置FLASH延时周期为5WS，也就是6个CPU周期 */
  if (ret != HAL_OK) {
    return 1; /* 时钟初始化失败 */
  }

  /* STM32F405x/407x/415x/417x Z版本的器件支持预取功能 */
  if (HAL_GetREVID() == 0x1001) {
    __HAL_FLASH_PREFETCH_BUFFER_ENABLE(); /* 使能flash预取 */
  }
  return 0;
}

/* USER CODE BEGIN 4 */
/**
 * @brief       通用定时器TIM6 作为系统时间基准 1ms中断一次
 * @note
 *              通用定时器的时钟来自APB1,当PPRE1 ≥ 2分频的时候
 *              通用定时器的时钟为APB1时钟的2倍, 而APB1为42M, 所以定时器时钟 =
 * 84Mhz 定时器溢出时间计算方法: Tout = ((arr + 1) * (psc + 1)) / Ft us.
 *              Ft=定时器工作频率,单位:Mhz
 *
 * @param       arr: 自动重装值
 * @param       psc: 预分频系数
 * @retval      无
 */
void gtim_tim6_int_init(void) {
  __HAL_RCC_TIM6_CLK_ENABLE(); /* 使能TIM6时钟 */

  g_tim6_handle.Instance = TIM6;                       /* 通用定时器2 */
  g_tim6_handle.Init.Prescaler = 84 - 1;               /* 预分频系数 */
  g_tim6_handle.Init.CounterMode = TIM_COUNTERMODE_UP; /* 递增计数模式 */
  g_tim6_handle.Init.Period = 1000 - 1;                /* 自动装载值 */
  HAL_TIM_Base_Init(&g_tim6_handle);

  HAL_NVIC_SetPriority(TIM6_DAC_IRQn, 1,
                       3); /* 设置中断优先级，抢占优先级1，子优先级3 */
  HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn); /* 开启ITM2中断 */

  HAL_TIM_Base_Start_IT(&g_tim6_handle); /* 使能定时器2和定时器2更新中断 */
}
/**
 * @brief 这是 TIM6 的中断服务函数，当中断发生时会自动调用该函数
 *
 */
void TIM6_DAC_IRQHandler(void) {
  HAL_TIM_IRQHandler(
      &g_tim6_handle); /*调用 HAL
                          库提供的定时器中断处理函数，对定时器的中断进行处理。*/
  /*检查定时器的更新标志位是否被置位。若被置位，表明定时器发生了溢出事件。*/
  if (__HAL_TIM_GET_FLAG(&g_tim6_handle, TIM_FLAG_UPDATE) != RESET) {
    /*清除定时器的更新中断标志位，防止重复触发中断。*/
    __HAL_TIM_CLEAR_IT(&g_tim6_handle, TIM_IT_UPDATE);
  }
}

/**
 * @brief 1ms定时器回调函数
 *
 */
void SysTick_USR_cb(void) {
  gWms++;
  if (gWms > 999) {
    gWms = gWms - 1000;
    GWs[0]++;
    GWs[1]++;
    GWs[2]++;
    GWs[3]++;
    GWs[4]++;
    GWs[5]++;
    GWs[6]++;
    GWs[7]++;
    GWs[8]++;
    GWs[9]++;
  }
  /*********串口接收的控制**********/
  if (ser3_RdStep == 1) {
    ser3_RdTime++;
    if (ser3_RdTime > 20) // 20ms收不到数据
    {
      ser3_RdFlag = 1; // 标志1说明接收完成1包数据。
      ser3_RdStep =
          0; // 置0，不在应用程序清零了。应用程序，只控制ser1_read_flag1。
    }
  }
}
// 1ms定时器处理函数
void timer_int_1ms(void) {
  // 1ms执行一次
  SysTick_USR_cb();
  // update_all_timer_on_state(); // 更新所有定时器的状态
}

/**
 * @brief 这是定时器溢出回调函数，当定时器发生溢出事件时，HAL_TIM_IRQHandler
 * 函数会调用此回调函数。
 *
 * @param htim
 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
  /* USER CODE BEGIN Callback 0 */
  /*定时器6中断*/
  if (htim->Instance == TIM6) {
    HAL_IncTick();
    /* USER CODE END Callback 0 */

    /* USER CODE BEGIN Callback 1 */
    system_run_time++; // 运行时间ms
    timer_int_1ms();
  }
  /* USER CODE END Callback 1 */
}
/* USER CODE END 4 */

/**
 * @brief  This function is executed in case of error occurrence.
 * @retval None
 */
void Error_Handler(void) {
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1) {
  }
  /* USER CODE END Error_Handler_Debug */
}
void startup(void) {
  init_DB0(); // 初始化DB0数据块
  init_DB1(); // 初始化DB1数据块
  memset(Input, 0, sizeof(Input));
  memset(Output, 0, sizeof(Output));
  // 初始化检测器
  init_rising_detector(&rising_edge_detector, rising_edge_buffer, 10);
  // 动态绑定变量
  bind_rising_variable(&rising_edge_detector, &(Input[0].bit0));
  bind_rising_variable(&rising_edge_detector, &(Input[0].bit1));
  // 初始化定时器
  init_all_timers_on();
  // 绑定定时器
  // TON1.input = &Input[0].bit2; // 第三个输入
  TON1.input = &DB0_t->Input[0].bit2; // 第三个输入
  TON1.preset = 3000;                 // 3秒
  TON2.input = &DB0_t->Input[0].bit3; // 第四个输入
  TON2.preset = 2000;                 // 2秒
}
void update_io(void) {
  // 更新输入输出状态
  // 输入状态读取

  Input[0].bit0 = !HAL_GPIO_ReadPin(I00_GPIO_Port, I00_Pin);
  Input[0].bit1 = !HAL_GPIO_ReadPin(I01_GPIO_Port, I01_Pin);
  Input[0].bit2 = !HAL_GPIO_ReadPin(I02_GPIO_Port, I02_Pin);
  Input[0].bit3 = !HAL_GPIO_ReadPin(I03_GPIO_Port, I03_Pin);
  Input[0].bit4 = !HAL_GPIO_ReadPin(I04_GPIO_Port, I04_Pin);
  Input[0].bit5 = !HAL_GPIO_ReadPin(I05_GPIO_Port, I05_Pin);
  Input[0].bit6 = !HAL_GPIO_ReadPin(I06_GPIO_Port, I06_Pin);
  Input[0].bit7 = !HAL_GPIO_ReadPin(I07_GPIO_Port, I07_Pin);
  // 普通
  Input[1].bit0 = !HAL_GPIO_ReadPin(I08_GPIO_Port, I08_Pin);
  Input[1].bit1 = !HAL_GPIO_ReadPin(I09_GPIO_Port, I09_Pin);
  Input[1].bit2 = !HAL_GPIO_ReadPin(I10_GPIO_Port, I10_Pin);
  Input[1].bit3 = !HAL_GPIO_ReadPin(I11_GPIO_Port, I11_Pin);
  Input[1].bit4 = !HAL_GPIO_ReadPin(I12_GPIO_Port, I12_Pin);
  Input[1].bit5 = !HAL_GPIO_ReadPin(I13_GPIO_Port, I13_Pin);
  // 输出
  Output[0].bit0 = HAL_GPIO_ReadPin(Q00_GPIO_Port, Q00_Pin);
  Output[0].bit1 = HAL_GPIO_ReadPin(Q01_GPIO_Port, Q01_Pin);
  Output[0].bit2 = HAL_GPIO_ReadPin(Q02_GPIO_Port, Q02_Pin);
  Output[0].bit3 = HAL_GPIO_ReadPin(Q03_GPIO_Port, Q03_Pin);
  Output[0].bit4 = HAL_GPIO_ReadPin(Q04_GPIO_Port, Q04_Pin);
  Output[0].bit5 = HAL_GPIO_ReadPin(Q05_GPIO_Port, Q05_Pin);
  // 高速
  Output[0].bit6 = HAL_GPIO_ReadPin(Q06_GPIO_Port, Q06_Pin);
  Output[0].bit7 = HAL_GPIO_ReadPin(Q07_GPIO_Port, Q07_Pin);
  Output[1].bit0 = HAL_GPIO_ReadPin(Q08_GPIO_Port, Q08_Pin);
  Output[1].bit1 = HAL_GPIO_ReadPin(Q09_GPIO_Port, Q09_Pin);
  // 更新输入输出状态
  // 输入状态读取

  DB0_t->Input[0].bit0 = !HAL_GPIO_ReadPin(I00_GPIO_Port, I00_Pin);
  DB0_t->Input[0].bit1 = !HAL_GPIO_ReadPin(I01_GPIO_Port, I01_Pin);
  DB0_t->Input[0].bit2 = !HAL_GPIO_ReadPin(I02_GPIO_Port, I02_Pin);
  DB0_t->Input[0].bit3 = !HAL_GPIO_ReadPin(I03_GPIO_Port, I03_Pin);
  DB0_t->Input[0].bit4 = !HAL_GPIO_ReadPin(I04_GPIO_Port, I04_Pin);
  DB0_t->Input[0].bit5 = !HAL_GPIO_ReadPin(I05_GPIO_Port, I05_Pin);
  DB0_t->Input[0].bit6 = !HAL_GPIO_ReadPin(I06_GPIO_Port, I06_Pin);
  DB0_t->Input[0].bit7 = !HAL_GPIO_ReadPin(I07_GPIO_Port, I07_Pin);
  // 普通
  DB0_t->Input[1].bit0 = !HAL_GPIO_ReadPin(I08_GPIO_Port, I08_Pin);
  DB0_t->Input[1].bit1 = !HAL_GPIO_ReadPin(I09_GPIO_Port, I09_Pin);
  DB0_t->Input[1].bit2 = !HAL_GPIO_ReadPin(I10_GPIO_Port, I10_Pin);
  DB0_t->Input[1].bit3 = !HAL_GPIO_ReadPin(I11_GPIO_Port, I11_Pin);
  DB0_t->Input[1].bit4 = !HAL_GPIO_ReadPin(I12_GPIO_Port, I12_Pin);
  DB0_t->Input[1].bit5 = !HAL_GPIO_ReadPin(I13_GPIO_Port, I13_Pin);
  // 输出
  DB0_t->Output[0].bit0 = HAL_GPIO_ReadPin(Q00_GPIO_Port, Q00_Pin);
  DB0_t->Output[0].bit1 = HAL_GPIO_ReadPin(Q01_GPIO_Port, Q01_Pin);
  DB0_t->Output[0].bit2 = HAL_GPIO_ReadPin(Q02_GPIO_Port, Q02_Pin);
  DB0_t->Output[0].bit3 = HAL_GPIO_ReadPin(Q03_GPIO_Port, Q03_Pin);
  DB0_t->Output[0].bit4 = HAL_GPIO_ReadPin(Q04_GPIO_Port, Q04_Pin);
  DB0_t->Output[0].bit5 = HAL_GPIO_ReadPin(Q05_GPIO_Port, Q05_Pin);
  // 高速
  DB0_t->Output[0].bit6 = HAL_GPIO_ReadPin(Q06_GPIO_Port, Q06_Pin);
  DB0_t->Output[0].bit7 = HAL_GPIO_ReadPin(Q07_GPIO_Port, Q07_Pin);
  DB0_t->Output[1].bit0 = HAL_GPIO_ReadPin(Q08_GPIO_Port, Q08_Pin);
  DB0_t->Output[1].bit1 = HAL_GPIO_ReadPin(Q09_GPIO_Port, Q09_Pin);
}
void updata_io_set(void) {
  // 输出
  HAL_GPIO_WritePin(Q00_GPIO_Port, Q00_Pin, (GPIO_PinState)Output[0].bit0);
  HAL_GPIO_WritePin(Q01_GPIO_Port, Q01_Pin, (GPIO_PinState)Output[0].bit1);
  HAL_GPIO_WritePin(Q02_GPIO_Port, Q02_Pin, (GPIO_PinState)Output[0].bit2);
  HAL_GPIO_WritePin(Q03_GPIO_Port, Q03_Pin, (GPIO_PinState)Output[0].bit3);
  HAL_GPIO_WritePin(Q04_GPIO_Port, Q04_Pin, (GPIO_PinState)Output[0].bit4);
  HAL_GPIO_WritePin(Q05_GPIO_Port, Q05_Pin, (GPIO_PinState)Output[0].bit5);
  // 高速
  HAL_GPIO_WritePin(Q06_GPIO_Port, Q06_Pin, (GPIO_PinState)Output[0].bit6);
  HAL_GPIO_WritePin(Q07_GPIO_Port, Q07_Pin, (GPIO_PinState)Output[0].bit7);
  HAL_GPIO_WritePin(Q08_GPIO_Port, Q08_Pin, (GPIO_PinState)Output[1].bit0);
  HAL_GPIO_WritePin(Q09_GPIO_Port, Q09_Pin, (GPIO_PinState)Output[1].bit1);
}
#ifdef USE_FULL_ASSERT
/**
 * @brief  Reports the name of the source file and the source line number
 *         where the assert_param error has occurred.
 * @param  file: pointer to the source file name
 * @param  line: assert_param error line source number
 * @retval None
 */
void assert_failed(uint8_t *file, uint32_t line) {
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line
     number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file,
     line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
